﻿#pragma once

#include "precomp.h"
#include "bullet.h"
#include "enemy.h"
#include "effect.h"
#include "player.h"
#include "resources.h"

class Bullet;
class Enemy;
class Effect;

// Базовые классы

class Appearance {
  public:
    Appearance();
    virtual ~Appearance();
    virtual void Render(CL_GraphicContext &gc, Bullet *p_bullet)=0;
};

class Effect_Appearance {
  public:
    Effect_Appearance();
    virtual ~Effect_Appearance();
    virtual int Render(CL_GraphicContext &gc, Effect *p_effect)=0;
};

class Enemy_Appearance {
  public:
    Enemy_Appearance();
    virtual ~Enemy_Appearance();
    virtual void Render(CL_GraphicContext &gc, Enemy *p_enemy)=0;
	virtual int RenderDead(CL_GraphicContext &gc, Enemy *p_enemy)=0;
//	virtual CL_Size GetSpriteSize();
};

class Boss_Appearance: public Enemy_Appearance {
  public:
    Boss_Appearance();
    virtual ~Boss_Appearance();
    virtual void RenderBack(CL_GraphicContext &gc, Enemy *p_enemy, float time)=0;
	virtual void RenderFront(CL_GraphicContext &gc, Enemy *p_enemy, float time)=0;
//	virtual CL_Size GetSpriteSize();
};

// Менеджер объектов-обработчиков

class RenderManager{
public:
	RenderManager();
	~RenderManager();
	void Init(CL_GraphicContext &gc, CL_ResourceManager &resources);
	Appearance* GetBulletRender(CL_String name);
	Enemy_Appearance* GetEnemyRender(CL_String name);
	Effect_Appearance* GetEffectRender(CL_String name);
	//Object_Appearance* GetObjectRender(CL_String name);
private:
	std::map<std::string, Appearance*> bullet_renders;
	std::map<std::string, Enemy_Appearance*> enemy_renders;
	std::map<std::string, Effect_Appearance*> effect_renders;
};

extern RenderManager renders;

// Конкретные обработчики

// ==========================================================
// Рендеры пуль
// ==========================================================

class Appearance_Simple : public Appearance {
public:
	Appearance_Simple(CL_String sprite_name, int frame_offset=0);
	virtual void Render(CL_GraphicContext &gc, Bullet *p_bullet);
private:
	CL_Sprite *sprite;
	int index;
	int offset;
};

class Appearance_Simple_Zoomed : public Appearance {
public:
	Appearance_Simple_Zoomed(CL_String sprite_name, int frame_offset=0, float z=1.0f);
	virtual void Render(CL_GraphicContext &gc, Bullet *p_bullet);
private:
	CL_Sprite *sprite;
	int index;
	int offset;
	float zoom;
};

class Appearance_Bullet_Pike : public Appearance {
public:
	Appearance_Bullet_Pike(CL_String sprite_name, int frame_offset=0);
	virtual void Render(CL_GraphicContext &gc, Bullet *p_bullet);
private:
	CL_Sprite *sprite;
	int index;
	int offset;
};

class Appearance_Player_Bullet1 : public Appearance {
public:
	Appearance_Player_Bullet1();
	virtual void Render(CL_GraphicContext &gc, Bullet *p_bullet);
};

class Appearance_Player_Bullet_Focus1 : public Appearance {
public:
	Appearance_Player_Bullet_Focus1(float f);
	virtual void Render(CL_GraphicContext &gc, Bullet *p_bullet);
private:
	float f_scale;
};

class Appearance_Player_Bullet2 : public Appearance {
public:
	Appearance_Player_Bullet2();
	virtual void Render(CL_GraphicContext &gc, Bullet *p_bullet);
};

// ============   Лазоры   ========================
// простой прямой лазор
class Appearance_Lazor : public Appearance {
public:
	Appearance_Lazor();
	virtual void Render(CL_GraphicContext &gc, Bullet *p_bullet);
private:
	CL_Sprite *sprite;
	CL_Sprite *sprite_tip;
	int index;
};


// ==========================================================
// Рендеры врагов
// ==========================================================

// Простая феечка
class Enemy_Appearance_Fairy : public Enemy_Appearance{
public:
	Enemy_Appearance_Fairy(int ring, int lights, CL_String f_sprite);
	virtual void Render(CL_GraphicContext &gc, Enemy *p_enemy);
	virtual int RenderDead(CL_GraphicContext &gc, Enemy *p_enemy);
//	virtual CL_Size GetSpriteSize();
private:
	CL_Sprite *sprite;
	CL_Sprite *sprite_splash;
	CL_Sprite *sprite_ring;
	CL_Sprite *sprite_big_ring;
	CL_Sprite *sprite_lights;
	int show_ring;
	int show_lights;
};

// Кедама
class Enemy_Appearance_Kedama : public Enemy_Appearance{
public:
	Enemy_Appearance_Kedama();
	virtual void Render(CL_GraphicContext &gc, Enemy *p_enemy);
	virtual int RenderDead(CL_GraphicContext &gc, Enemy *p_enemy);
private:
	CL_Sprite *sprite;
	CL_Sprite *sprite_splash;
};

// Босс тип 1 (Летти)
class Enemy_Appearance_Boss1 : public Boss_Appearance{
public:
	Enemy_Appearance_Boss1(CL_String name);
	virtual void Render(CL_GraphicContext &gc, Enemy *p_enemy);
	virtual int RenderDead(CL_GraphicContext &gc, Enemy *p_enemy);
	virtual void RenderBack(CL_GraphicContext &gc, Enemy *p_enemy, float time);
	virtual void RenderFront(CL_GraphicContext &gc, Enemy *p_enemy, float time);
private:
	CL_Sprite *sprite;
	CL_Sprite *sprite_splash;
};

// ==========================================================
// Рендеры эффектов
// ==========================================================

class Appearance_Effect_Magic_Flash : public Effect_Appearance {
public:
	Appearance_Effect_Magic_Flash();
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
	int index;
};

class Appearance_Effect_Enemy_Shot1 : public Effect_Appearance {
public:
	Appearance_Effect_Enemy_Shot1(float dur);
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
	int index;
	float duration;
};

class Appearance_Effect_Enemy_Shot2 : public Effect_Appearance {
public:
	Appearance_Effect_Enemy_Shot2(float dur);
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
	int index;
	float duration;
};

class Appearance_Effect_Enemy_Shot_Cloud1 : public Effect_Appearance {
public:
	Appearance_Effect_Enemy_Shot_Cloud1(float dur);
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
	int index;
	float duration;
};

class Appearance_Effect_Score_Float : public Effect_Appearance {
public:
	Appearance_Effect_Score_Float(CL_GraphicContext &gc, CL_ResourceManager &resources);
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Font_Sprite *bonus_score_font;
	CL_Sprite *font_sprite;
};

class Appearance_Effect_Player_Bullet_Hit1 : public Effect_Appearance {
public:
	Appearance_Effect_Player_Bullet_Hit1();
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
};

// Пули в фокусе
class Appearance_Effect_Player_Bullet_Hit2 : public Effect_Appearance {
public:
	Appearance_Effect_Player_Bullet_Hit2(float f);
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	float f_scale;
};

class Appearance_Effect_Player_Bullet_Hit3 : public Effect_Appearance {
public:
	Appearance_Effect_Player_Bullet_Hit3();
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
};

class Appearance_Effect_Enemy_Bullet_Hit1 : public Effect_Appearance {
public:
	Appearance_Effect_Enemy_Bullet_Hit1();
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
	int index;
};

class Appearance_Effect_Cancelled_Bullet : public Effect_Appearance {
public:
	Appearance_Effect_Cancelled_Bullet();
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite1;
	CL_Sprite *sprite2;
	int index;
};

class Appearance_Effect_Happa_Particle : public Effect_Appearance {
public:
	Appearance_Effect_Happa_Particle();
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
};

class Appearance_Effect_Snow_Particle : public Effect_Appearance {
public:
	Appearance_Effect_Snow_Particle();
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
};

class Appearance_Effect_Small_Particle : public Effect_Appearance {
public:
	Appearance_Effect_Small_Particle();
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
};

class Appearance_Effect_Graze_Particle : public Effect_Appearance {
public:
	Appearance_Effect_Graze_Particle();
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
};

class Appearance_Effect_Letty_Cloud : public Effect_Appearance {
public:
	Appearance_Effect_Letty_Cloud(float dur);
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
	float duration;
};

class Appearance_Effect_Boss_Name : public Effect_Appearance {
public:
	Appearance_Effect_Boss_Name();
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *sprite;
};

class Appearance_Effect_Spellcard_Result : public Effect_Appearance {
public:
	Appearance_Effect_Spellcard_Result (CL_GraphicContext &gc, CL_ResourceManager &resources);
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Font_Sprite *_score_font;
	CL_Sprite *font_sprite;
};

class Appearance_Effect_Spellcard_Name : public Effect_Appearance {
public:
	Appearance_Effect_Spellcard_Name (CL_GraphicContext &gc, CL_ResourceManager &resources);
	virtual int Render(CL_GraphicContext &gc, Effect *p_effect);
private:
	CL_Sprite *_sprite;
};
